package dao

import models.Tables._
import play.api.db.slick.{DatabaseConfigProvider, HasDatabaseConfigProvider}
import slick.jdbc.JdbcProfile

import javax.inject.Inject
import scala.concurrent.{ExecutionContext, Future}

class BlockRangeDao @Inject()(protected val dbConfigProvider: DatabaseConfigProvider)
                             (implicit exec: ExecutionContext) extends
  HasDatabaseConfigProvider[JdbcProfile] {

  import profile.api._

  def insert(row: Seq[BlockrangeRow]): Future[Unit] = {
    db.run(Blockrange ++= row).map(_ => ())
  }

  def getByQuery(query: String): Future[Seq[BlockrangeRow]] = {
    db.run(Blockrange.filter(_.querySpecies === query).result)
  }

  def getBySpecies(s1: String, s2: String): Future[Seq[BlockrangeRow]] = {
    db.run(Blockrange.filter(x => (x.querySpecies === s1 && x.refSpecies === s2) || (x.refSpecies === s1 && x.querySpecies === s2)).result)
  }

  def getById(id: Int): Future[BlockrangeRow] = {
    db.run(Blockrange.filter(_.id === id).result.head)
  }

  def getByPos(species: String, chr: String, start: Int, end: Int): Future[Seq[BlockrangeRow]] = {
    db.run(Blockrange.filter(x => (x.querySpecies === species && x.query === chr && x.queryStart <= start && x.queryEnd >= end) ||
      (x.refSpecies === species && x.ref === chr && x.refStart <= start && x.refEnd >= end)).result)
  }

  def getBySpeciesAndChr(species: String, chr: String): Future[Seq[String]] = {
    db.run(for {
      q <- Blockrange.filter(_.querySpecies === species).filter(_.query === chr).map(_.refSpecies).result
      r <- Blockrange.filter(_.refSpecies === species).filter(_.ref === chr).map(_.querySpecies).result
    } yield q ++ r)
  }

  def getComparison(species: String, chr: String, dbs: Seq[String]): Future[Seq[BlockrangeRow]] = {
    db.run(Blockrange.filter(x =>
      (x.querySpecies === species && x.query === chr && x.refSpecies.inSetBind(dbs)) ||
        (x.refSpecies === species && x.ref === chr && x.querySpecies.inSetBind(dbs))
    ).result)
  }

  def exsitBlockId(blockId:String) : Future[Seq[BlockrangeRow]] = {
    db.run(Blockrange.filter(_.name === blockId).result)
  }

}
